//
//  BoardView.m
//  CocOth
//
//  Created by BrunoCausse on 03/11/10.
//  Copyright 2010-2013 poulailler cie. All rights reserved.
//

#import "BC_BoardView.h"
#import "NSFileManager+DirectoryLocations.h"

#import "BC_Utils.h"
#import "BC_BoardController.h"





@implementation BC_BoardView

- (id)initWithFrame:(NSRect)frame {
	
    self = [super initWithFrame:frame];
    if (self) {
		
        // Initialization code here.
		//on charge les images
		sqImages = [[NSMutableArray alloc] init];
		
		showCoordinated = NO;
    }
    return self;
}

- (void)awakeFromNib
{
	tagImages = [[NSArray alloc] initWithObjects:	[NSImage imageNamed:@"b1"],
				 [NSImage imageNamed:@"b2"],
				 [NSImage imageNamed:@"b3"],
				 [NSImage imageNamed:@"b4"],
				 [NSImage imageNamed:@"b5"], nil];
	
	[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSStringPboardType, nil]];
	dragDropLigthFlag = NO;

}
	

- (void)dealloc
{
	[tagImages release];
	[sqImages release];
	[super dealloc];
}



#pragma mark surcharge

- (BOOL)isFlipped
{
	return YES;
}


- (void)drawRect:(NSRect)dirtyRect {
	
		
		
	
	NSColor *bgColor = [NSColor blackColor];
	if ([controller player]) {
		bgColor = [NSColor whiteColor];
	}
	
	NSColor *fgColor = [NSColor redColor];
	

	//attributs de texte
	NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
	[attributes setObject:[NSFont fontWithName:@"Helvetica" 
										  size:12]
				   forKey:NSFontAttributeName];
	[attributes setObject:fgColor 
				   forKey:NSForegroundColorAttributeName];
	
	NSSize capSize = [@"X" sizeWithAttributes:attributes];

	
	//desiner un othellier
	NSRect bounds = [self bounds], rectImage;

	[bgColor set];
	[NSBezierPath fillRect:bounds];
	
	

	//le cadre
	float frameSize = capSize.height; //proportionnel a la fenetre
	float width  = bounds.size.width  - 2*frameSize;
	float height = bounds.size.height - 2*frameSize;
	float sqSize = min(width, height)/8.0;
	float xMin   = (width  - 8*sqSize)/2 + frameSize;
	float yMin   = (height - 8*sqSize)/2 + frameSize;
	
	//cadre de l'othellier
	boardRect.origin.x = xMin;
	boardRect.origin.y = yMin;
	boardRect.size.width = boardRect.size.height = 8*sqSize;
	
	//dessous othellier
	[[NSColor blackColor] set];
	[NSBezierPath fillRect:boardRect];
	
	if(showCoordinated) {

		const NSString *absice = @"ABCDEFGH";
		
		NSRect rect;
		rect.size.width = capSize.width;
		rect.size.height = capSize.height;

		for(int column = 0; column < 8; column++) {
			
			//Affichage des lettres/colonnes
			NSRange r = NSMakeRange(column, 1);
			NSString *letter = [absice substringWithRange:r];
			rect.origin.x= xMin - capSize.width + column*sqSize + (sqSize + capSize.width)/2;
			rect.origin.y = yMin - capSize.height;
			
			[letter drawInRect:rect withAttributes:attributes];
			
			//affichage des chiffres/lignes
			//Attention pour les chiffres des lignes je me sert des index des colonnes
			NSString *number = [NSString stringWithFormat:@"%d", column+1];
			rect.origin.x= xMin - capSize.width;
			rect.origin.y = yMin - capSize.height + column*sqSize + (sqSize + capSize.height)/2;
			
			[number drawInRect:rect withAttributes:attributes];
		}
	}
		

	//attributs de texte
	NSMutableDictionary *attributesVariation = [[NSMutableDictionary alloc] init];
	[attributesVariation setObject:[NSFont fontWithName:@"Helvetica" 
										  size:12]
				   forKey:NSFontAttributeName];
	[attributesVariation setObject:[NSColor blackColor]
				   forKey:NSForegroundColorAttributeName];
	

	//attributs de texte
	NSMutableDictionary *attributesScore = [[NSMutableDictionary alloc] init];
	[attributesScore setObject:[NSFont fontWithName:@"Helvetica" 
										  size:12]
				   forKey:NSFontAttributeName];
	[attributesScore setObject:[NSColor whiteColor] 
				   forKey:NSForegroundColorAttributeName];
	
	for(int column = 0; column < 8; column++) {
		
		for( int row = 0; row < 8; row++) {
			
			rectImage.origin.x = xMin + column*sqSize;
			rectImage.origin.y = yMin + row*sqSize;
			rectImage.size.width = rectImage.size.height = sqSize;
			
			int disc = [controller discAtRow:row column:column];
			if (showLegalsMove && [controller isLegalAtRow:row column:column]) {
					disc = 3;
			}
						
			[[sqImages objectAtIndex:disc] drawInRect:rectImage 
									 fromRect:NSZeroRect
									operation: NSCompositeCopy
											 fraction: dragDropLigthFlag? 0.75:1.0];
			
			//variation
			if([controller isLegalAtRow:row column:column]) {
				
				NSString *variation = [controller nameVariationAtRow:row column:column];
				if(variation) {
					//affichage au milieu de la case
					NSSize variationSize = [variation sizeWithAttributes:attributesVariation];
					NSRect rect;
					rect.size.width  = variationSize.width;
					rect.size.height = variationSize.height;
					rect.origin.x = rectImage.origin.x + (sqSize - variationSize.width )/2;
					rect.origin.y = rectImage.origin.y + (sqSize - variationSize.height)/2;
					
					[variation drawInRect:rect withAttributes:attributesVariation];
				}
				
				NSString *score = [controller scoreAtRow:row column:column];
				if (score) {
					
					//affichage en bas de la case
					NSSize scoreSize = [score sizeWithAttributes:attributesScore];
					NSRect rect;
					rect.size.width  = scoreSize.width;
					rect.size.height = scoreSize.height;
					rect.origin.x = rectImage.origin.x + (sqSize - scoreSize.width )/2;
					rect.origin.y = rectImage.origin.y + 1;
					
					[score drawInRect:rect withAttributes:attributesScore];
				}
				
				int tag = [controller tagAtRow:row column:column];
				if(tag>=0) {
					
					rectImage.origin.x += 9*sqSize/16;
					rectImage.origin.y += 9*sqSize/16;
					rectImage.size.width = rectImage.size.height -= 10*sqSize/16;

					[[tagImages objectAtIndex:tag] drawInRect:rectImage 
													 fromRect:NSZeroRect
													operation: NSCompositeSourceOver
													fraction: dragDropLigthFlag? 0.75:1.0];
//											   respectFlipped:NO 
//														hints:nil];
					
				}
				
			}
		}
	}
	
	[attributesScore release];
	[attributesVariation release];
	[attributes release];

	
}

- (NSMenu *)menuForEvent:(NSEvent *)event
{
	NSPoint popUpLocation = [self convertPoint:[event locationInWindow] fromView:nil];
	
	if ([self mouse:popUpLocation inRect:boardRect]) {
		
		//localisation square
		float sqSize = boardRect.size.width/8.0;
		int column	= floor((popUpLocation.x - boardRect.origin.x)/sqSize);
		int row		= floor((popUpLocation.y - boardRect.origin.y)/sqSize);
		
		if([controller isLegalAtRow:row column:column]) {
			popUpAtRowColumn = NSMakePoint(row, column);

			for(int i = 0; i<5; i++)
				[[contextual itemWithTag:i]setState:NSOffState];

			int tag = [controller tagAtRow:popUpAtRowColumn.x column:popUpAtRowColumn.y];
			if(tag>=0) {
				NSMenuItem *menuItem = [contextual itemWithTag:tag];
				[menuItem setState:NSOnState];
			}
			

			return contextual;
		}
		
	}
	
	return nil;
}

#pragma mark actions

- (IBAction)setTagImage:(id)sender
{
	
	int tag = -1;
	if ([sender state] == NSOffState) {
		tag = [sender tag];
	}

		
	//verifier si la variation existe sinon la creer
	if([controller nameVariationAtRow:popUpAtRowColumn.x column:popUpAtRowColumn.y] == nil) {
		[controller	addVariationAtRow:popUpAtRowColumn.x column:popUpAtRowColumn.y];
	}
	
	//lui affecter l'image
	[controller setTag:tag atRow:popUpAtRowColumn.x column:popUpAtRowColumn.y];

	[self setNeedsDisplay:YES];

}

- (IBAction)removeVariation:(id)sender
{
	[controller removeVariationAtRow:popUpAtRowColumn.x column:popUpAtRowColumn.y];
}
	
	

#pragma mark Utilities

- (void)loadDesign2D:(NSString *)folderName
{
	[sqImages removeAllObjects];

	if ([folderName isEqual:@"default"]) {
		
		[sqImages addObject:[NSImage imageNamed:@"Black"]];
		[sqImages addObject:[NSImage imageNamed:@"White"]];
		[sqImages addObject:[NSImage imageNamed:@"Empty"]];
		[sqImages addObject:[NSImage imageNamed:@"Legal"]];
		[sqImages addObject:[NSImage imageNamed:@"Sugested"]];
		
		
	} else {
		
		// le dossier design2D devrait se trouver dans /Library/Application Support/CocOth/design2D

		NSString *executableName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
		NSString *appendPath = [executableName stringByAppendingPathComponent:@"design 2D"];
		appendPath =[appendPath stringByAppendingPathComponent:folderName];
		
				
		NSError *error;
		NSString *images2DPath = [[NSFileManager defaultManager]findOrCreateDirectory:NSApplicationSupportDirectory
																			 inDomain:NSUserDomainMask
																  appendPathComponent:appendPath
																				error:&error];
					
		
		NSBundle *pathImage = [NSBundle bundleWithPath:images2DPath];

		
		NSString *blackPath = [pathImage pathForImageResource:@"Black"];
		NSString *whitePath = [pathImage pathForImageResource:@"White"];
		NSString *emptyPath = [pathImage pathForImageResource:@"Empty"];
		NSString *legalPath = [pathImage pathForImageResource:@"Legal"];
		NSString *sugestedPath = [pathImage pathForImageResource:@"Sugested"];
		
		
		NSImage *blackImage = [[NSImage alloc] initWithContentsOfFile:blackPath];
		[sqImages addObject:blackImage];
		[blackImage release];
		
		NSImage *whiteImage = [[NSImage alloc] initWithContentsOfFile:whitePath];
		[sqImages addObject:whiteImage];
		[whiteImage release];

		NSImage *emptyImage = [[NSImage alloc] initWithContentsOfFile:emptyPath];
		[sqImages addObject:emptyImage];
		[emptyImage release];

		NSImage *legalImage = [[NSImage alloc] initWithContentsOfFile:legalPath];
		[sqImages addObject:legalImage];
		[legalImage release];

		NSImage *sugestedImage = [[NSImage alloc] initWithContentsOfFile:sugestedPath];
		[sqImages addObject:sugestedImage];
		[sugestedImage release];
	}
	
	
	[self setNeedsDisplay:YES];
	
}

- (void)showHideCoordinated 
{
	showCoordinated = !showCoordinated;
	[self setNeedsDisplay:YES];
}


#pragma mark Events

- (void)mouseUp:(NSEvent *)theEvent
{
	
	blackTrait = !blackTrait;

    NSPoint location = [self convertPoint: [theEvent locationInWindow] fromView: NO];
	
	if(NSPointInRect(location, boardRect)) {
		
		float sqSize = boardRect.size.width/8.0;
		int column	= floor((location.x - boardRect.origin.x)/sqSize);
		int row		= floor((location.y - boardRect.origin.y)/sqSize);
		
		if([controller doMoveAtRow:row column:column]) {
			showLegalsMove = NO;
		} else {
			showLegalsMove = !showLegalsMove;
			//probleme avec pass
			if ([controller shouldPass]) {
				[self setNeedsDisplay:YES];
			}
		}
	}

	[self setNeedsDisplay:YES];


}

- (void)keyDown:(NSEvent *)theEvent
{

	if([theEvent keyCode] == 124) {
		if(![controller forward])
			NSBeep();
	} else if([theEvent keyCode] == 123) {
		if(![controller backstep])
			NSBeep();
	}
}

/*accepte le 1er clic*/
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
	return YES;
}

/*accepte les event clavier*/
- (BOOL)acceptsFirstResponder
{
	return YES;
}

- (BOOL)resignFirstResponder
{
	return YES;
}

- (BOOL)becomeFirstResponder
{
	return YES;
}

#pragma mark Drag&Drop

//entre dans la zone
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
	dragDropLigthFlag = YES;
	[self setNeedsDisplay:YES];
	
	NSPasteboard *pboard = [sender draggingPasteboard];

	
	if ([[[sender draggingPasteboard] types] containsObject:NSFilenamesPboardType])
	{
		NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
		if ([filenames count] == 1)
		{
			NSString *filename = [filenames objectAtIndex:0];
			if([[filename pathExtension] isEqual:@"othelist"] || [[filename pathExtension] isEqual:@"coth"])
				return NSDragOperationCopy;
		}
	}

	if ([[[sender draggingPasteboard] types] containsObject:NSStringPboardType])
	{
		NSString *s = [pboard stringForType:NSStringPboardType];
		
		if(s != nil)
			return NSDragOperationCopy;
	}
	
	return NSDragOperationNone;
	
}

// est dans la zone
//- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
//{
//
//	return [self draggingEntered:sender];
//}


//sort de la zone
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
	dragDropLigthFlag = NO;
	[self setNeedsDisplay:YES];
	
}


//init de l'op de drag
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
	return YES;
}

// l’opération à effectuer lors du drag
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
	NSPasteboard *pboard = [sender draggingPasteboard];
	
	if ([[pboard types] containsObject:NSFilenamesPboardType])
	{
		NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
		if ([filenames count] == 1)
		{
			NSString *filename = [filenames objectAtIndex:0];
			if([[filename pathExtension] isEqual:@"othelist"] || [[filename pathExtension] isEqual:@"coth"])
				[controller openFile:filename];
		}
		return YES;
	}

	if ([[pboard types] containsObject:NSStringPboardType])
	{
		
		NSString *s = [pboard stringForType:NSStringPboardType];

		if(s != nil)
			[controller tryParseString:s];
		
		return YES;
	}
	
	
	return NO;
}

//apres l'op de drag
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
	dragDropLigthFlag = NO;
	[self setNeedsDisplay:YES];

}



@end
